package com.haitao.wavebbs.controller.security;

import com.haitao.wavebbs.entity.tools.ResponseData;
import com.haitao.wavebbs.tools.SecurityTools;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.CodeSignature;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.HashMap;
import java.util.Map;

/**
 * 代理每个需要用户登录的controller接口，验证token是否可用，若可用则提取token中的用户信息，并传递给下个方法
 *
 * @author haitao
 * @data 2023/3/14
 */
@Aspect
@Component
public class AuthorizationAspect {
    @Pointcut("@within(org.springframework.stereotype.Controller) || @within(org.springframework.web.bind.annotation.RestController)")
    public void controller() {
    }

    @Pointcut("@annotation(checkToken)")
    private void checkToken() {
    }

    @Pointcut("checkToken()&&controller()")
    private void checkTokenAndcontroller() {
    }

    @Around("checkTokenAndcontroller()")
    public Object  checkTokenAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
        try {
            String authorization = request.getHeader("authorization");
            String newToken = authorization.replace("Bearer ", "");
            Integer userId =  (Integer) SecurityTools.getClaimsFromJwt(newToken).get("userId");
            request.setAttribute("userId", userId);
            return joinPoint.proceed();
        } catch (Exception e) {
            return new ResponseEntity(new ResponseData("权限不足",null), HttpStatus.UNAUTHORIZED);
        }
    }
}
